// #include<stdio.h>
// int main()
// {
//     printf("hello world\n");
//     return 0;
// }

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int g_unval;//全局未初始化变量
int g_val = 10;//全局初始化变量

int main(int argc , char* argv[] , char* env[])
{
    const char* str = "hello world!";
    printf("code addr:%p\n" , main);
    printf("init global addr:%p\n" , &g_val);
    printf("uninit global addr:%p\n" , &g_unval);

    static int cnt = 10;
    char* heap_men1 = (char*)malloc(10);
    char* heap_men2 = (char*)malloc(10);
    char* heap_men3 = (char*)malloc(10);
    printf("headp addr: %p\n" , heap_men1);
    printf("headp addr: %p\n" , heap_men2);
    printf("headp addr: %p\n" , heap_men3);

    printf("test static addr:%p\n" , &cnt);
    printf("stack addr:%p\n" , &heap_men1);
    printf("stack addr:%p\n" , &heap_men2);
    printf("stack addr:%p\n" , &heap_men3);

    printf("read only string addr: %p\n" ,str);//字符串常量
    for(int i = 0;argv[i];i++)
    {
        printf("argv[%d] : %p\n" , i , argv[i]);//命令行参数
    }
    for(int i = 0;env[i];i++)
    {
        printf("env[%d] : %p\n" , i, env[i]);//环境变量
    }

    return 0;
}

// #include<stdio.h>
// #include<unistd.h>

// //全局变量
// int g_val = 100;

// int main()
// {
//     pid_t id = fork();
//     if(id == 0)
//     {
//         //子进程
//         while(1)
//         {
//             printf("子进程：pid: %d , ppid : %d , g_val: %d , &g_val: %p\n", getpid() , getppid() , g_val , &g_val);
//             g_val++;
//             sleep(1);
//         }
//     }

//     //父进程
//     while(1)
//     {
//         printf("父进程: pid: %d , ppid: %d , g_val: %d , &g_val: %p\n" , getpid() , getppid() , g_val , &g_val);
//         sleep(1);
//     }
//     return 0;
// }

// #include<stdio.h>
// #include<unistd.h>
// #include<stdbool.h>
// #include<stdlib.h>
// #include<sys/types.h>
// #include<sys/wait.h>
// #include<string>
// #include<iostream>

// int main()
// {
//     //子进程写，父进程读
//     //创建管道文件，fork 创建子进程，父子进程关闭自己不用的文件描述符，父子进程进行通信
//     int pipefd[2] = {0};
//     int n = pipe(pipefd);
//     if(n == -1) 
//     {
//         perror("pipe");
//         exit(1);
//     }

//     //创建子进程
//     pid_t id = fork();
//     if(id < 0)
//     {
//         perror("fork");
//         exit(1);
//     }
//     else if( id == 0)
//     {
//         //子进程
//         //pipefd[0]
//         close(pipefd[0]);

//         //子进程向管道写入数据
//         // std::string str = "我是子进程,我的pid: ";
//         // std::string pid = std::to_string(getpid());
//         // str = str + pid + ',';
//         int cnt = 10;
//         while(cnt)
//         {
//             // std::string message = str + std::to_string(++cnt);
//             // // std::cout << " 子进程写入：ing"<<std::endl; 
//             // write(pipefd[1] , message.c_str(), message.size());
//             // sleep(1);
//             char c = 'A' + cnt;
//             write(pipefd[1],&c,1);//写端一直写，读端不读--> 写端写满了就不再写了
//             printf("count: %d , %s\n" , cnt , &c);
//             sleep(1);
//             cnt--;
//         }
//         std::cout << "写端关闭" <<std::endl;
//         close(pipefd[1]);
//         sleep(2);
//         exit(0);//子进程退出
//     }

//     //父进程
//     //关闭pipefd[1]
//     close(pipefd[1]);
//     //父进程读取管道中的数据
//     while(true)
//     {
//         // char buffer[1024]={0};
//         // std::cout << "父进程读取: ing" <<std::endl;
//         // int n = read(pipefd[0] , buffer , sizeof(buffer)-1);
//         // if(n > 0)
//         // {
//         //     buffer[n] =0;

//         //     printf("父进程读取到了数据: %s\n" , buffer);
//         // }
//     }
//     //父进程等待子进程
//     pid_t rid = waitpid(id , nullptr , 0);
//     if(rid < 0)
//     {
//         perror("waitpid");
//         exit(1);
//     }

//     return 0;
// }

// int main()
// {
//     int piped[2]={0};
//     int n = pipe(piped);
//     if(n==0)
//     {
//         printf("创建管道成功: piped[0] : %d , piped[1] : %d \n" , piped[0] , piped[1]);
//     }
//     return 0;
// }